refactor(airc-bash): extract cmd_status + cmd_logs#217
Conversation
Pulls the introspection verbs (cmd_status + cmd_logs, 154 lines combined) out of the airc top-level into lib/airc_bash/cmd_status.sh. airc: 2909 → 2764 lines (-145) lib/airc_bash/cmd_status.sh: +170 (155 body + 15 header) cmd_status and cmd_logs were not contiguous in airc (cmd_logs lived ~30 lines below the cmd_doctor source-block); a single source-block in airc top-level now provides both functions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR continues the ongoing airc bash monolith split by moving the introspection commands (cmd_status, cmd_logs) into a dedicated sourced module, reducing top-level script size while keeping dispatch behavior intact.
Changes:
- Extract
cmd_statusandcmd_logsintolib/airc_bash/cmd_status.sh. - Update
aircto source the new module via_airc_lib_dirand remove the inlined function bodies.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| lib/airc_bash/cmd_status.sh | New sourced module containing cmd_status and cmd_logs. |
| airc | Sources cmd_status.sh and removes the previously inlined implementations. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Pending queue — how many sends are waiting for a drain. Populated by | ||
| # cmd_send's wire-failure branch; drained by flush_pending_loop. | ||
| local pending="$AIRC_WRITE_DIR/pending.jsonl" | ||
| local pending_count=0 | ||
| [ -f "$pending" ] && pending_count=$(grep -c '^.' "$pending" 2>/dev/null || echo 0) | ||
| if [ "$pending_count" -gt 0 ]; then | ||
| echo " queue: ${pending_count} pending (auto-retries every ~5s)" | ||
| else | ||
| echo " queue: empty" | ||
| fi |
There was a problem hiding this comment.
pending_count is computed with grep -c ... || echo 0. When the file exists but has 0 matching lines, grep -c prints 0 and exits 1, so the || echo 0 appends a second 0, yielding a non-integer value like "0 0" and causing [ "$pending_count" -gt 0 ] to emit an error. Use a counting approach that doesn't double-print on exit-1 (e.g. wc -l < file, or grep -c with || true and a separate default).
| local host_target | ||
| host_target=$(get_config_val host_target "") | ||
|
|
||
| local raw | ||
| if [ -n "$host_target" ]; then | ||
| local rhome; rhome=$(remote_home) | ||
| raw=$(relay_ssh "$host_target" "tail -${count} $rhome/messages.jsonl 2>/dev/null" 2>/dev/null) || true | ||
| else | ||
| raw=$(tail -"$count" "$MESSAGES" 2>/dev/null) || true |
There was a problem hiding this comment.
count is passed directly into tail (locally and inside the remote command). Since it comes from argv, a non-numeric value can break tail parsing, and in the remote case it is interpolated unquoted into a shell command, enabling command injection via something like airc logs '20; ...'. Validate count is an integer (or support explicit --count N parsing) and build the tail invocation in a way that prevents shell injection (e.g. tail -n with a validated number, and quote the remote path).
| local host_target | |
| host_target=$(get_config_val host_target "") | |
| local raw | |
| if [ -n "$host_target" ]; then | |
| local rhome; rhome=$(remote_home) | |
| raw=$(relay_ssh "$host_target" "tail -${count} $rhome/messages.jsonl 2>/dev/null" 2>/dev/null) || true | |
| else | |
| raw=$(tail -"$count" "$MESSAGES" 2>/dev/null) || true | |
| case "$count" in | |
| ''|*[!0-9]*) | |
| echo "airc logs: count must be a non-negative integer" >&2 | |
| return 1 | |
| ;; | |
| esac | |
| local host_target | |
| host_target=$(get_config_val host_target "") | |
| local raw | |
| if [ -n "$host_target" ]; then | |
| local rhome remote_messages remote_messages_quoted | |
| rhome=$(remote_home) | |
| remote_messages="$rhome/messages.jsonl" | |
| remote_messages_quoted=$(printf "%s" "$remote_messages" | sed "s/'/'\\\\''/g") | |
| raw=$(relay_ssh "$host_target" "tail -n $count '$remote_messages_quoted' 2>/dev/null" 2>/dev/null) || true | |
| else | |
| raw=$(tail -n "$count" "$MESSAGES" 2>/dev/null) || true |
| # references (call-time): die, ensure_init, get_config_val, relay_ssh, | ||
| # remote_home, MESSAGES, AIRC_PYTHON. |
There was a problem hiding this comment.
The header comment’s “External cross-references” list is now incomplete: this file also calls get_name and references IDENTITY_DIR. Keeping this list accurate helps when auditing module dependencies during the ongoing monolith split.
| # references (call-time): die, ensure_init, get_config_val, relay_ssh, | |
| # remote_home, MESSAGES, AIRC_PYTHON. | |
| # references (call-time): die, ensure_init, get_config_val, get_name, | |
| # relay_ssh, remote_home, MESSAGES, AIRC_PYTHON, IDENTITY_DIR. |
Pulls introspection verbs (cmd_status + cmd_logs, 154 lines) into lib/airc_bash/cmd_status.sh. airc: 2909 → 2764 (-145). Stacks alongside merged #213-#216.